<?php namespace xlx;

use Workerman\Connection\TcpConnection;
use Workerman\Connection\AsyncTcpConnection;
use \Workerman\Events\EventInterface;
 
class Process
{ 
    /**
     * 真进程 
     */
    public static function fork($fn,$args=[])
    {   
        \Hprose\Future\co(function()use($fn,$args){
            try{
                yield $fn($args);
            }catch(\Throwable $e){
                echo $e; 
            } 
        });
        return;

        static $include;
        if (empty($include)) {
            foreach (get_declared_classes() as $composer) {
                if (substr($composer, 0, 22)=='ComposerAutoloaderInit') {
                    $ref = new \ReflectionClass($composer);
                    $file = $ref->getFileName();
                    $class = xlx\OTPWorker::class;
                    $include = "require_once '$file';$composer::getLoader();";
                }
            }
        }
        if (empty($include)) {
            throw new Exception("Error Processing Request", 1);
        }
        if(\is_array($fn)){
            $fn = \var_export($fn,true); 
        }else{
            $fn = 'unserialize(base64_decode(\''.base64_encode(serialize(new \Opis\Closure\SerializableClosure($fn)) ). '\'))';
        }
        $string = '\Hprose\Future\co('.$fn.','.preg_replace("/[\r\n]+/",'',var_export($args,true)).')'
                .'->then(null, function ($e) { echo $e; /* \xlx\Process::exit(); */    });';     
        if (strpos(strtolower(PHP_OS), 'win') === 0) {
            popen($c = 'start /B '.\PHP_BINARY.' -r "'.$include
                ."class_alias(\xlx\Windows\Events\Select::class, \Workerman\Events\Select::class);" 
                .' /*window select*/ '.$string, 'w' ); 
        } else { 
            popen(\PHP_BINARY.' -r "eval(base64_decode(\''.base64_encode($include.$string).'\'));" &>nil ','w');
        }
    }


 

    public static function checkAddr($addr){
        preg_match('/([\d\.]+):(\d+)/',$addr,$arr);
        if($arr[2] > 65536){
            throw new \Exception("Error Port Number", 1); 
        } 
        $addr = "{$arr[1]}:{$arr[2]}";
        if (strpos(strtolower(PHP_OS), 'win') === 0) {
            return !!\system("netstat -ano|findstr $addr");
        } else {
            //ubuntu bash on windows10 not support
            return !!\system("netstat -anp|grep $addr"); 
        }
    }

    // public static function start($fn){
    //     $local = new AChannel();
    //     $self = $local->self();
    //     self::spawn(function($event)use($fn,$self){
    //         $actor = new AChannel();
    //         $actor->send($self,yield $fn($actor));
    //         //zisa
    //     });
    //     return $local->receive(function($val) { return $val; });
    // }

    public static function terminate(){

    }

    public static function delay($time)
    {
        $deferred = new \Hprose\Deferred;

        $event = \Workerman\Worker::$globalEvent;
        $event->add($time, EventInterface::EV_TIMER_ONCE,function()use($deferred){
            $deferred->resolve(null);
        });
        return $deferred->promise;//();
        // return new \React\Promise\Promise(function ($next) use ($time) {
        //     $event = \Workerman\Worker::$globalEvent;
        //     $event->add($time, EventInterface::EV_TIMER_ONCE,$next);
            
        //     //  function()use($next){
        //     //     $next();
        //     //     // $GLOBALS['_'] = new class{
        //     //     //     function __destruct(){
        //     //     //         ($this->next)();
        //     //     //     }
        //     //     // };
        //     //     // $GLOBALS['_']->next=$next;
        //     // });
        // });
    } 

    public static function createEventLoop()
    {
        $method = new \ReflectionMethod(\Workerman\Worker::class, 'getEventLoopName');
        $method->setAccessible(true);
        $CLASS = $method->invoke(null);
        return \Workerman\Worker::$globalEvent = new $CLASS;
    }

    static $lock;
    public static function exit(){   
        \xlx\co(function() {
            $i=1;
            while($i++){
                yield self::delay(0.1);
                $a = \xlx\lib\WeakRef::$obj;
                $b = \xlx\lib\WeakRef::$gcc;
                if(!count(\xlx\lib\WeakRef::$obj)) { 
                    echo "[DIE]";
                    exit;
                } 
            }
          
        }); 
    }
}
 